/*
*    UNIVERSIDADE DE SÃO PAULO.
*    Author: Marco Aurélio Gerosa (gerosa@ime.usp.br)
*    This project was/is sponsored by RNP and FAPESP.
*
*    This file is part of Groupware Workbench (http://www.groupwareworkbench.org.br).
*
*    Groupware Workbench is free software: you can redistribute it and/or modify
*    it under the terms of the GNU Lesser General Public License as published by
*    the Free Software Foundation, either version 3 of the License, or
*    (at your option) any later version.
*
*    Groupware Workbench is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU Lesser General Public License for more details.
*
*    You should have received a copy of the GNU Lesser General Public License
*    along with Swift.  If not, see <http://www.gnu.org/licenses/>.
*/
package br.org.groupwareworkbench.eureka.knowledge;

import br.org.groupwareworkbench.core.bd.ObjectDAO;
import br.org.groupwareworkbench.core.framework.Collablet;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Table;

@Entity
@Table(name="Knowledge")
public class Knowledge implements Serializable {

    private static final long serialVersionUID = 4820172445307827729L;

    private static ObjectDAO<Knowledge, Long> DAO = new ObjectDAO<Knowledge, Long>(Knowledge.class);

    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne
    private Collablet collablet;

    // adicionado do código do original da AUN
    private String codReg;

    private String title;

    @Column(/*columnDefinition="MEDIUMTEXT",*/ length=20480)
    private String cause;

    @Column(/*columnDefinition="MEDIUMTEXT",*/ length=20480)
    private String area;
    
    @Column(/*columnDefinition="MEDIUMTEXT",*/ length=20480)
    private String solution;

    private String chave;
    
    @Temporal(TemporalType.TIMESTAMP)
    private Date publishDate;

    public Knowledge(String cause) {
        this();
        this.cause = cause;
    }

    public Knowledge() {
        this.publishDate = new Date();
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof Knowledge)) return false;
        Knowledge other = (Knowledge) o;

        Long otherId = other.getId();
        String otherTitle = other.getTitle();
        Collablet otherCollablet = other.getCollablet();

        return (id == null ? otherId == null : id.equals(otherId)) &&
                (title == null ? otherTitle == null : title.equals(otherTitle)) &&
                (collablet == null ? otherCollablet == null : collablet.equals(otherCollablet));
    }

    @Override
    public int hashCode() {
        return (id == null ? 0 : id.hashCode()) ^
                (title == null ? 0 : title.hashCode()) ^
                (collablet == null ? 0 : collablet.hashCode());
    }

    public void save() {
        DAO.save(this);
    }

    public void delete() {
        DAO.delete(this);
    }

    public static Knowledge findById(long id) {
        return DAO.findById(id);
    }

    public static Knowledge findByTitle(String title, Collablet collablet) {
        if (collablet == null) throw new IllegalArgumentException();
        if (title == null) throw new IllegalArgumentException();
        return DAO.query()
                .with("collablet", collablet)
                .with("title", title)
                .find();
    }

    public static List<Knowledge> list(Collablet collablet) {
        if (collablet == null) throw new IllegalArgumentException();
        return DAO.query().with("collablet", collablet).list();
    }

    private static final Pattern ESCAPE_HTML = Pattern.compile("<+[A-Za-z0-9.:!^#@&\\?\\*\\(\\)\\[\\]_%\\$+-/\\\"\'= ]+>");

    private static String escapeHtml(String str) {
        return str == null ? null :
            ESCAPE_HTML.matcher(str).replaceAll(" ").replaceAll(" +", " ").trim().replaceAll("\r\n", " ");
    }

    public Long getId() {
        return id;
    }

    // Deve ser usado apenas pelo VRaptor.
    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public String getEscapedTitle() {
        return escapeHtml(title);
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getCause() {
        return cause;
    }

    public String getEscapedCause() {
        return escapeHtml(cause);
    }
    
    public void setCause(String cause) {
        this.cause = cause;
    }

    public String getArea() {
        return area;
    }

    public void setArea(String area) {
        this.area = area;
    }
    
    public String getSolution() {
        return solution;
    }

    public void setSolution(String solution) {
        this.solution = solution;
    }

    public String getChave() {
        return chave;
    }

    public void setChave(String chave) {
        this.chave = chave;
    }
    
    public String getEscapedSolution() {
        return escapeHtml(solution);
    }

    public String getCodReg() {
        return codReg;
    }

    public void setCodReg(String codReg) {
        this.codReg = codReg;
    }

    public Date getPublishDate() {
        return publishDate == null ? null : (Date) publishDate.clone();
    }

    public void setPublishDate(Date publishDate) {
        this.publishDate = publishDate == null ? null : (Date) publishDate.clone();
    }

    public Collablet getCollablet() {
        return collablet;
    }

    public void setCollablet(Collablet collablet) {
        this.collablet = collablet;
    }
}